package com.ljb.android.comm.mvp

import android.annotation.SuppressLint
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.Nullable
import androidx.annotation.StringRes
import androidx.viewbinding.ViewBinding
import com.gyf.immersionbar.ImmersionBar
import com.gyf.immersionbar.components.ImmersionOwner
import com.gyf.immersionbar.components.ImmersionProxy
import com.ljb.android.comm.BuildConfig
import com.ljb.android.comm.R
import com.ljb.android.comm.databinding.CommLayoutLoadingDialogBinding
import com.ljb.android.comm.databinding.CommLayoutTitlebarBinding
import com.ljb.android.comm.utils.XLog
import com.ljb.android.comm.weiget.page.PageState
import com.ljb.android.comm.weiget.page.PageStateLayout
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshFooter
import com.scwang.smart.refresh.layout.api.RefreshHeader
import mvp.ljb.kt.contract.IPresenterContract
import mvp.ljb.kt.fragment.BaseMvpFragment
import org.greenrobot.eventbus.EventBus


abstract class CommMvpFragment<out P : IPresenterContract, B : ViewBinding> :
    BaseMvpFragment<P>(), ICommView, ImmersionOwner {

    companion object {
        /**
         * Page 全屏模式
         * */
        @JvmStatic
        val MODE_PAGE_FULL = 1

        /**
         * Page Title底部模式
         * */
        @JvmStatic
        val MODE_PAGE_TITLE = 2
    }


    /**
     * ImmersionBar代理类
     */
    private val mImmersionProxy by lazy { ImmersionProxy(this) }

    /**
     * Root View
     * */
    protected lateinit var mRootView: ViewGroup

    /**
     * 内容 View
     * */
    private lateinit var mContentView: RelativeLayout

    /**
     * 页面管理布局 ，需@superPage() 返回true
     * */
    protected var mPageLayout: PageStateLayout? = null

    /**
     * 拖拽\刷新 Layout
     * */
    private var mRefreshLayout: SmartRefreshLayout? = null

    /**
     * Title布局 ViewBind
     * @需要: supportTitle() return true
     * */
    protected var mTitleView: View? = null

    /**
     * Loading布局 ViewBind
     * */
    protected lateinit var mBindLoading: CommLayoutLoadingDialogBinding

    /**
     * 业务布局 ViewBind
     * */
    protected lateinit var mBind: B

    private var mIsUIVisibleFlag = false
    private var mIsCreateViewFlag = false

    abstract fun registerBinding(inflater: LayoutInflater, parent: ViewGroup): B

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mImmersionProxy.onCreate(savedInstanceState)
        initOther()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return initContentView(inflater, container)
    }


    private fun initContentView(inflater: LayoutInflater, container: ViewGroup?): View {
        // contentView
        mContentView = RelativeLayout(context).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            setBackgroundResource(R.color.bg_page)
        }

        // contentBind
        mBind = registerBinding(inflater, mContentView)

        // title view
        if (supportTitle()) {
            initTitleBar(layoutInflater)
        }

        // 上下拖拽 Layout
        if (supportDraw() || supportRefresh() || supportLoadMore()) {
            initDrawLayout()
        } else {
            initCenterView()
        }

        // loading view
        initLoadingView(inflater)

        // rootView
        initRootView()

        mIsCreateViewFlag = true

        return mRootView
    }

    private fun initRootView() {
        mRootView = if (supportPage()) {
            when (pageMode()) {
                MODE_PAGE_FULL -> {
                    // 全屏模式之前没有加入PageStateLayout,现在加
                    PageStateLayout(requireContext(), pageTag())
                        .apply {
                            this.setContentView(mContentView)
                            this.setRetryPageListener { onPageRetry() }
                            mPageLayout = this
                        }
                }
                MODE_PAGE_TITLE -> {
                    // 之前加过了，直接返回
                    mContentView
                }
                else -> {
                    // 未知模式之前没有加入PageStateLayout,现在加
                    PageStateLayout(requireContext(), pageTag())
                        .apply {
                            this.setContentView(mContentView)
                            this.setRetryPageListener { onPageRetry() }
                            mPageLayout = this
                        }
                }
            }
        } else {
            mContentView
        }
    }

    private fun initTitleBar(inflater: LayoutInflater) {
        mTitleView = customTitleView(inflater, mContentView)
        if (mTitleView != null) {
            // 自定义TitleView
            mTitleView?.findViewById<View>(R.id.iv_toolbar_left)
                ?.setOnClickListener { activity?.onBackPressed() }
            mTitleView?.findViewById<View>(R.id.tv_toolbar_left)
                ?.setOnClickListener { activity?.onBackPressed() }
            mTitleView?.setPadding(0, ImmersionBar.getStatusBarHeight(this), 0, 0)
        } else {
            // 默认TitleView
            val titleBind = CommLayoutTitlebarBinding.inflate(inflater, mContentView, false)
            titleBind.ivToolbarLeft.setOnClickListener { activity?.onBackPressed() }
            titleBind.tvToolbarLeft.setOnClickListener { activity?.onBackPressed() }
            titleBind.root.setPadding(0, ImmersionBar.getStatusBarHeight(this), 0, 0)
            mTitleView = titleBind.root
        }
        mContentView.addView(mTitleView)
    }


    private fun initLoadingView(inflater: LayoutInflater) {
        mBindLoading = CommLayoutLoadingDialogBinding.inflate(inflater, mContentView, false)
        mContentView.addView(mBindLoading.root)
    }

    private fun initDrawLayout() {
        // 拖拽Layout
        mRefreshLayout = SmartRefreshLayout(context)

        val layoutParams = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )

        if (supportTitle()) {
            layoutParams.addRule(RelativeLayout.BELOW, mTitleView!!.id)
        }

        // 开发要展示的内容
        val centerLayoutParams = SmartRefreshLayout.LayoutParams(
            SmartRefreshLayout.LayoutParams.MATCH_PARENT,
            SmartRefreshLayout.LayoutParams.WRAP_CONTENT
        )
        mRefreshLayout?.addView(mBind.root, centerLayoutParams)

        // 添加到页面上
        if (supportPage()) {
            when (pageMode()) {
                MODE_PAGE_FULL -> {
                    // 全屏Page模式，直接加入开发内容
                    mContentView.addView(mRefreshLayout, layoutParams)
                }
                MODE_PAGE_TITLE -> {
                    // 标题Page模式
                    PageStateLayout(requireContext(), pageTag())
                        .apply {
                            this.setContentView(mRefreshLayout!!)
                            this.setRetryPageListener { onPageRetry() }
                            mPageLayout = this
                            mContentView.addView(this, layoutParams)
                        }
                }
                else -> {
                    // 未知模式，直接加
                    mContentView.addView(mRefreshLayout, layoutParams)
                }
            }
        } else {
            mContentView.addView(mRefreshLayout, layoutParams)
        }

        // 开启上下拖拽功能
        setEnableRefresh(supportDraw())
        setEnableLoadMore(supportDraw())

        // 添加刷新Header
        if (supportRefresh()) {
            mRefreshLayout?.apply {
                setRefreshHeader(customRefreshHeader())
                setEnableHeaderTranslationContent(true)
                setEnableRefresh(true)
                setOnRefreshListener { onRefresh() }
            }
        }

        // 添加加载Footer
        if (supportLoadMore()) {
            mRefreshLayout?.apply {
                setRefreshFooter(customRefreshFooter())
                setEnableLoadMore(true)
                setOnLoadMoreListener { onLoadMore() }
            }
        }
    }

    private fun initCenterView() {
        // 开发要展示的内容
        val layoutParams = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )
        if (supportTitle()) {
            layoutParams.addRule(RelativeLayout.BELOW, mTitleView!!.id)
        }

        if (supportPage()) {
            when (pageMode()) {
                MODE_PAGE_FULL -> {
                    // 全屏Page模式，直接加入开发内容
                    mContentView.addView(mBind.root, layoutParams)
                }
                MODE_PAGE_TITLE -> {
                    // 标题Page模式
                    PageStateLayout(requireContext(), pageTag())
                        .apply {
                            this.setContentView(mBind.root)
                            this.setRetryPageListener { onPageRetry() }
                            mPageLayout = this
                            mContentView.addView(this, layoutParams)
                        }
                }
                else -> {
                    // 未知模式，直接加
                    mContentView.addView(mBind.root, layoutParams)
                }
            }
        } else {
            mContentView.addView(mBind.root, layoutParams)
        }
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        mImmersionProxy.isUserVisibleHint = isVisibleToUser
        mIsUIVisibleFlag = isVisibleToUser
//        XLog.e(javaClass.simpleName + " 执行 setUserVisibleHint()：$mIsCreateViewFlag  $mIsUIVisibleFlag")
        if (mIsUIVisibleFlag && mIsCreateViewFlag) {
            lazyData()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onDestroy() {
        super.onDestroy()
        mImmersionProxy.onDestroy()
        unOther()
    }

    private fun initOther() {
        initEventBus()
    }

    private fun unOther() {
        unEventBus()
    }

    private fun initEventBus() {
        if (supportEventBus() && !EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    private fun unEventBus() {
        if (supportEventBus() && EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
    }

    private fun setLoading(isShow: Boolean) {
        mBindLoading.root.visibility = if (isShow) View.VISIBLE else View.GONE
    }

    /**
     * 显示Loading弹窗
     * */
    override fun showLoading() {
        setLoading(true)
    }

    /**
     * 隐藏Loading弹窗
     * */
    override fun hideLoading() {
        setLoading(false)
    }

    protected fun setTitleText(
        @StringRes resId: Int,
        @ColorInt colorId: Int = resources.getColor(R.color.color_333)
    ) {
        setTitleText(getText(resId), colorId)
    }

    protected fun setTitleText(
        text: CharSequence,
        @ColorInt colorId: Int = resources.getColor(R.color.color_333)
    ) {
        if (supportTitle()) {
            mTitleView?.findViewById<TextView>(R.id.tv_toolbar_center)?.apply {
                setText(text)
                setTextColor(colorId)
            }
        }
    }

    protected fun setTitleLeftImage(
        @DrawableRes resId: Int,
        listener: View.OnClickListener? = null
    ) {
        if (supportTitle()) {
            mTitleView?.findViewById<ImageView>(R.id.iv_toolbar_left)?.apply {
                setImageResource(resId)
                setOnClickListener(listener)
                visibility = View.VISIBLE
            }
            mTitleView?.findViewById<View>(R.id.tv_toolbar_left)?.visibility = View.GONE
        }
    }

    protected fun setTitleLeftText(
        @StringRes resId: Int,
        listener: View.OnClickListener? = null
    ) {
        setTitleLeftText(getText(resId), listener)
    }

    protected fun setTitleLeftText(text: CharSequence, listener: View.OnClickListener? = null) {
        if (supportTitle()) {
            mTitleView?.findViewById<TextView>(R.id.tv_toolbar_left)?.apply {
                setText(text)
                setOnClickListener(listener)
                visibility = View.VISIBLE
            }
            mTitleView?.findViewById<View>(R.id.iv_toolbar_left)?.visibility = View.GONE
        }
    }

    protected fun setTitleRightImage(
        @DrawableRes resId: Int,
        listener: View.OnClickListener? = null
    ) {
        if (supportTitle()) {
            mTitleView?.findViewById<ImageView>(R.id.iv_toolbar_right)?.apply {
                setImageResource(resId)
                setOnClickListener(listener)
                visibility = View.VISIBLE
            }
            mTitleView?.findViewById<View>(R.id.tv_toolbar_right)?.visibility = View.GONE
        }
    }

    protected fun setTitleRightText(@StringRes resId: Int, listener: View.OnClickListener? = null) {
        setTitleRightText(getText(resId), listener)
    }

    protected fun setTitleRightText(text: CharSequence, listener: View.OnClickListener? = null) {
        if (supportTitle()) {
            mTitleView?.findViewById<TextView>(R.id.tv_toolbar_right)?.apply {
                setText(text)
                setOnClickListener(listener)
                visibility = View.VISIBLE
            }
            mTitleView?.findViewById<View>(R.id.iv_toolbar_right)?.visibility = View.GONE
        }
    }

    override fun onActivityCreated(@Nullable savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        mImmersionProxy.onActivityCreated(savedInstanceState)
        // 懒加载 配合setUserVisibleHint
//        XLog.e(javaClass.simpleName + " onActivityCreated 执行：lazyData() $mIsCreateViewFlag  $mIsUIVisibleFlag  isComponent<${BuildConfig.IS_COMPONENT}>")
        if ((mIsCreateViewFlag && mIsUIVisibleFlag) || BuildConfig.IS_COMPONENT) {
            lazyData()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onResume() {
        super.onResume()
        mImmersionProxy.onResume()
    }

    @SuppressLint("MissingSuperCall")
    override fun onPause() {
        super.onPause()
        mImmersionProxy.onPause()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        mImmersionProxy.onHiddenChanged(hidden)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        mImmersionProxy.onConfigurationChanged(newConfig)
    }

    /**
     * 懒加载，在view初始化完成之前执行
     * On lazy after view.
     */
    override fun onLazyBeforeView() {}

    /**
     * 懒加载，在view初始化完成之后执行
     * On lazy before view.
     */
    override fun onLazyAfterView() {}

    /**
     * Fragment用户可见时候调用
     * On visible.
     */
    override fun onVisible() {}

    /**
     * Fragment用户不可见时候调用
     * On invisible.
     */
    override fun onInvisible() {}

    /**
     * 是否可以实现沉浸式，当为true的时候才可以执行initImmersionBar方法
     * Immersion bar enabled boolean.
     *
     * @return the boolean
     */
    override fun immersionBarEnabled(): Boolean {
        return true
    }

    override fun initImmersionBar() {
        initStatusBar()
    }

    protected open fun initStatusBar() {
        ImmersionBar.with(this)
            .transparentStatusBar()     //透明状态栏，不写默认透明色
            .statusBarDarkFont(true) //状态栏字体是深色，不写默认为亮色
            .navigationBarDarkIcon(true) //导航栏图标是深色，不写默认为亮色
            .init()
    }

    private fun lazyData() {
        XLog.i(javaClass.simpleName + " -> lazyData()")
        lazyInitData()
        mIsUIVisibleFlag = false
        mIsCreateViewFlag = false
    }


    /**
     * 懒加载数据
     * 仅会执行一次
     * 建议在 ViewPager + Fragment场景中使用
     * */
    protected open fun lazyInitData() {

    }


    /**
     * 开发人员可以重写 -> 自定义加载更多
     * */
    private fun customRefreshFooter(): RefreshFooter {
        return ClassicsFooter(context)
    }

    /**
     * 加载更多开关
     * */
    protected fun setEnableLoadMore(enable: Boolean) {
        mRefreshLayout?.setEnableLoadMore(enable)
    }

    /**
     * 加载更多结束
     * */
    protected fun finishLoadMore(success: Boolean = true) {
        mRefreshLayout?.finishLoadMore(success)
    }

    /**
     * 加载更多结束
     * */
    protected fun setNoLoadMore(noMore: Boolean = true) {
        mRefreshLayout?.setNoMoreData(noMore)
    }

    /**
     * 下拉刷新回調
     * 仅在 supportRefresh() 返回true时，才会被执行
     * */
    protected open fun onLoadMore() {

    }

    /**
     * 开发人员可以重写 -> 自定义刷新头
     * */
    protected open fun customRefreshHeader(): RefreshHeader {
        return MaterialHeader(context).apply {
            setColorSchemeResources(
                R.color.color_39B6DF,
                R.color.color_1296DB,
                R.color.color_6385F8
            )
        }
    }

    /**
     * 刷新开关
     * */
    protected fun setEnableRefresh(enable: Boolean) {
        mRefreshLayout?.setEnableRefresh(enable)
    }

    /**
     * 刷新结束
     * */
    protected fun finishRefresh(success: Boolean = true) {
        mRefreshLayout?.finishRefresh(success)
    }

    /**
     * 仅播放刷新动画，不回调onRefresh
     * */
    protected fun autoRefreshAnimationOnly() {
        mRefreshLayout?.autoRefreshAnimationOnly()
    }

    /**
     * 触发刷新，并播放动画
     * */
    protected fun autoRefresh() {
        mRefreshLayout?.autoRefresh()
    }

    /**
     * 下拉刷新回調
     * 仅在 supportRefresh() 返回true时，才会被执行
     * */
    protected open fun onRefresh() {

    }

    /**
     * 页面出错重试
     * 默认执行  onRefresh() 或者 initData()
     * 开发人员可根据实际情况覆写该方法
     * */
    protected open fun onPageRetry() {
        if (supportRefresh()) {
            setPage(PageState.STATE_LOADING)
            onRefresh()
        } else {
            initData()
        }
    }

    /**
     * 自定义Title布局
     * */
    protected open fun customTitleView(
        layoutInflater: LayoutInflater,
        viewGroup: ViewGroup
    ): View? {
        return null
    }


    /**
     * 页面模式，分为两种
     * @MODE_PAGE_FULL : 全屏模式，页面状态全屏显示
     * @MODE_PAGE_TITLE : 标题模式，页面状态显示在标题下方
     * */
    protected open fun pageMode(): Int {
        return MODE_PAGE_TITLE
    }

    /**
     * 自定义使用哪套Page页面
     * */
    protected open fun pageTag(): String {
        return PageStateLayout.TAG_DEFAULT
    }

    /**
     * 切换页面状态
     * */
    protected fun setPage(page: PageState) {
        if (supportPage()) {
            mPageLayout?.setPage(page)
        }
    }

    /**
     * 设置内容的背景色
     * */
    protected fun setBackgroundColor(@ColorInt colorId: Int) {
        mContentView.setBackgroundColor(colorId)
    }

    /**
     * 是否支持 EventBus
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportEventBus() = false

    /**
     * 是否显示 TitleBar
     * @return true(显示)  false(不显示)
     * */
    protected open fun supportTitle() = false

    /**
     * 是否支持上下拖拽 Layout
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportDraw() = false

    /**
     * 是否支持下拉刷新
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportRefresh() = false

    /**
     * 是否支持加载更多
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportLoadMore() = false

    /**
     * 是否支持页面状态切换
     * @return true(支持)  false(不支持)
     * */
    protected open fun supportPage() = false

}